home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / joe014.zip / JOE014.TAZ / JOE014.tar / asyncposix.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  6KB  |  300 lines

  1. /* Terminal interface for POSIX
  2.    Copyright (C) 1991 Joseph H. Allen
  3.    (Contributed by Mike Lijewski)
  4.  
  5. This file is part of JOE (Joe's Own Editor)
  6.  
  7. JOE is free software; you can redistribute it and/or modify it under the terms
  8. of the GNU General Public License as published by the Free Software
  9. Foundation; either version 1, or (at your option) any later version.  
  10.  
  11. JOE is distributed in the hope that it will be useful, but WITHOUT ANY
  12. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  13. A PARTICULAR PURPOSE.  See the GNU General Public License for more details.  
  14.  
  15. You should have received a copy of the GNU General Public License along with
  16. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 675
  17. Mass Ave, Cambridge, MA 02139, USA.  */ 
  18.  
  19. #include <stdio.h>
  20. #include <signal.h>
  21. #include <fcntl.h>
  22. #include <sys/time.h>
  23. #include <sys/param.h>
  24. #include <termios.h>
  25. #include <unistd.h>
  26. #include "async.h"
  27.  
  28. void tsignal();
  29. #define DIVISOR 12000000
  30. #define TIMES 2
  31.  
  32. static struct termios oldterm;
  33.  
  34. static unsigned char *obuf=0;
  35. static unsigned obufp=0;
  36. static unsigned obufsiz;
  37. static unsigned long ccc;
  38.  
  39. static speed_t speeds[]=
  40. {
  41. B50,50,B75,75,B110,110,B134,134,B150,150,B200,200,B300,300,B600,600,B1200,1200,
  42. B1800,1800,B2400,2400,B4800,4800,B9600,9600,EXTA,19200,EXTB,38400,B19200,19200,
  43. B38400,38400
  44. };
  45.  
  46. esignal(a,b)
  47. void (*b)();
  48. {
  49. struct sigaction action;
  50. sigemptyset(&actions.sa_mask);
  51. action.sa_handler=b;
  52. sigaction(a,&action,NULL);
  53. }
  54.  
  55. sigjoe()
  56. {
  57. esignal(SIGHUP,tsignal);
  58. esignal(SIGTERM,tsignal);
  59. esignal(SIGPIPE,SIG_IGN);
  60. esignal(SIGINT,SIG_IGN);
  61. esignal(SIGQUIT,SIG_IGN);
  62. }
  63.  
  64. signorm()
  65. {
  66. esignal(SIGHUP,SIG_DFL);
  67. esignal(SIGTERM,SIG_DFL);
  68. esignal(SIGQUIT,SIG_DFL);
  69. esignal(SIGPIPE,SIG_DFL);
  70. esignal(SIGINT,SIG_DFL);
  71. }
  72.  
  73. aopen()
  74. {
  75. int x;
  76. speed_t baud;
  77. struct termios newterm;
  78. fflush(stdout);
  79. tcdrain(STDOUT_FILENO);
  80. tcgetattr(STDIN_FILENO,&oldterm);
  81. newterm=oldterm;
  82. newterm.c_lflag&=0;
  83. newterm.c_iflag&=~(ICRNL|IGNCR|INLCR);
  84. newterm.c_oflag&=0;
  85. newterm.c_cc[VMIN]=1;
  86. newterm.c_cc[VTIME]=0;
  87. tcsetattr(STDIN_FILENO,TCSANOW,&newterm);
  88. ccc=0;
  89. baud=cfgetospeed(&newterm);
  90. for(x=0;x!=34;x+=2)
  91.  if(baud==speeds[x])
  92.   {
  93.   ccc=DIVISOR/speeds[x+1];
  94.   break;
  95.   }
  96. if(obuf) free(obuf);
  97. if(!(TIMES*ccc)) obufsiz=4096;
  98. else
  99.  {
  100.  obufsiz=1000000/(TIMES*ccc);
  101.  if(obufsiz>4096) obufsiz=4096;
  102.  }
  103. if(!obufsiz) obufsiz=1;
  104. obuf=(unsigned char *)malloc(obufsiz);
  105. }
  106.  
  107. aclose()
  108. {
  109. aflush();
  110. tcsetattr(STDIN_FILENO,TCSANOW,&oldterm);
  111. }
  112.  
  113. int have=0;
  114. static unsigned char havec;
  115. static int yep;
  116.  
  117. static void dosig()
  118. {
  119. yep=1;
  120. }
  121.  
  122. aflush()
  123. {
  124. if(obufp)
  125.  {
  126.  struct itimerval a,b;
  127.  unsigned long usec=obufp*ccc;
  128.  if(usec>=500000/HZ)
  129.   {
  130.   a.it_value.tv_sec=usec/1000000;
  131.   a.it_value.tv_usec=usec%1000000;
  132.   a.it_interval.tv_usec=0;
  133.   a.it_interval.tv_sec=0;
  134.   action.sa_handler=dosig;
  135.   esignal(SIGALRM,dosig);
  136.   yep=0;
  137.   sigsetmask(sigmask(SIGALRM));
  138.   setitimer(ITIMER_REAL,&a,&b);
  139.   write(fileno(stdout),obuf,obufp);
  140.   while(!yep) sigpause(0);
  141.   esignal(SIGALRM,SIG_DFL);
  142.   }
  143.  else write(fileno(stdout),obuf,obufp);
  144.  obufp=0;
  145.  }
  146. if(!have)
  147.  {
  148.  fcntl(STDIN_FILENO,F_SETFL,O_NDELAY);
  149.  if(read(STDIN_FILENO,&havec,1)==1) have=1;
  150.  fcntl(STDIN_FILENO,F_SETFL,0);
  151.  }
  152. }
  153.  
  154. unsigned char *take=0;
  155.  
  156. anext()
  157. {
  158. if(take)
  159.  if(*take)
  160.   {
  161.   int c;
  162.   if(*take!='\\') return *take++;
  163.   ++take;
  164.   if(!*take) return '\\';
  165.   else if(*take=='r') c='\r';
  166.   else if(*take=='b') c=8;
  167.   else if(*take=='n') c=10;
  168.   else if(*take=='f') c=12;
  169.   else if(*take=='a') c=7;
  170.   else if(*take=='\"') c='\"';
  171.   else if(*take>='0' && *take<='7')
  172.         {
  173.         c= *take++-'0';
  174.         if(*take>='0' && *take<='7')
  175.          {
  176.          c=c*8+*take++-'0';
  177.          if(*take>='0' && *take<='7') c=c*8+*take++-'0';
  178.          }
  179.         --take;
  180.         }
  181.   else c= *take;
  182.   ++take;
  183.   return c;
  184.   }
  185.  else take=0;
  186. aflush();
  187. if(have) have=0;
  188. else if(read(STDIN_FILENO,&havec,1)<1) tsignal(0);
  189. if(record) macroadd(havec);
  190. return havec;
  191. }
  192.  
  193. eputc(c)
  194. unsigned char c;
  195. {
  196. obuf[obufp++]=c;
  197. if(obufp==obufsiz) aflush();
  198. }
  199.  
  200. eputs(s)
  201. char *s;
  202. {
  203. while(*s)
  204.  {
  205.  obuf[obufp++]= *(s++);
  206.  if(obufp==obufsiz) aflush();
  207.  }
  208. }
  209.  
  210. getsize()
  211. {
  212. #ifdef TIOCGSIZE
  213. struct ttysize getit;
  214. #else
  215. #ifdef TIOCGWINSZ
  216. struct winsize getit;
  217. #else
  218. char *p;
  219. #endif
  220. #endif
  221. #ifdef TIOCGSIZE
  222. if(ioctl(fileno(stdout),TIOCGSIZE,&getit)!= -1)
  223.  {
  224.  if(getit.ts_lines>=3) height=getit.ts_lines;
  225.  if(getit.ts_cols>=2) width=getit.ts_cols;
  226.  }
  227. #else
  228. #ifdef TIOCGWINSZ
  229. if(ioctl(fileno(stdout),TIOCGWINSZ,&getit)!= -1)
  230.  {
  231.  if(getit.ws_row>=3) height=getit.ws_row;
  232.  if(getit.ws_col>=2) width=getit.ws_col;
  233.  }
  234. #else
  235. if(p=getenv("ROWS")) sscanf(p,"%d",&height);
  236. if(p=getenv("COLS")) sscanf(p,"%d",&width);
  237. if(height<3) height=24;
  238. if(width<2) width=80;
  239. #endif
  240. #endif
  241. }
  242.  
  243. termtype()
  244. {
  245. unsigned char entry[1024];
  246. unsigned char area[1024];
  247. unsigned char *foo=area;
  248. unsigned char *x=(unsigned char *)getenv("TERM");
  249. if(!x) goto down;
  250. if(tgetent(entry,x)!=1) goto down;
  251. height=tgetnum("li");
  252. if(height<3) height=24;
  253. width=tgetnum("co");
  254. if(width<2) width=80;
  255. if(!tgetstr("cs",&foo)) scroll=0;
  256. down:
  257. getsize();
  258. }
  259.  
  260. shell()
  261. {
  262. int x;
  263. char *s=(char *)getenv("SHELL");
  264. if(!s)
  265.  {
  266.  puts("\nSHELL variable not set");
  267.  return;
  268.  }
  269. eputs("\nYou are at the command shell.  Type 'exit' to continue editing\r\n");
  270. aclose();
  271. if(x=fork())
  272.  {
  273.  if(x!= -1) wait(0);
  274.  }
  275. else
  276.  {
  277.  signorm();
  278.  execl(s,s,0);
  279.  _exit(0);
  280.  }
  281. aopen();
  282. }
  283.  
  284. susp()
  285. {
  286. #ifdef SIGCONT
  287. eputs("\nThe editor has been suspended.  Type 'fg' to continue editing\r\n");
  288. yep=0;
  289. aclose();
  290. esignal(SIGCONT,dosig);
  291. sigsetmask(sigmask(SIGCONT));
  292. kill(0,SIGTSTP);
  293. while(!yep) sigpause(0);
  294. esignal(SIGCONT,SIG_DFL);
  295. aopen();
  296. #else
  297. shell();
  298. #endif
  299. }
  300.